/*
 * game.c
 *
 *  Created on: 15 nov. 2010
 *      Author: Nicolas Aucouturier, Laurent R�veill�re
 */

#include <assert.h>
#include <time.h>

#include "../include/game.h"
#include "../include/map.h"
#include "../include/player.h"
#include "../include/misc.h"
#include "../include/level.h"
#include "../include/bomb.h"
#include "../include/monster.h"
#include "../include/bomb_list.h"
#include "../include/monster_list.h"
#include "../include/constant.h"

struct s_game {
	t_level curr_level; // current level
	t_player player;
	t_list bomb_list;

	t_list monster_list;
	//t_monster monster;
	SDL_Surface * number[10];
	SDL_Surface * banner_life;
	SDL_Surface * banner_bomb;
	SDL_Surface * banner_range;
	SDL_Surface * banner_line;
	SDL_Surface * banner_key;
};

static struct s_game the_game;

t_game game_new(void) {
	srand(time(NULL ));

	the_game.curr_level = level_get_level(0); // get maps of the first level

	the_game.player = player_init(BOMB_NB);
	player_from_map(the_game.player, level_get_map(the_game.curr_level, 0)); // get x,y of the player on the first map

	//the_game.monster=monster_init(3,4);

	the_game.monster_list = monster_list_init(monster_init(-1,-1));
	the_game.monster_list=monster_list_from_map(level_get_map(the_game.curr_level, 0), the_game.monster_list);

	the_game.bomb_list = bomb_list_init( bomb_new ( player_get_x(the_game.player), player_get_y(the_game.player), player_get_range_bomb(the_game.player)));


	/* load banner's imgs in memory */
	the_game.number[0] = load_image(IMG_BANNER_0);
	the_game.number[1] = load_image(IMG_BANNER_1);
	the_game.number[2] = load_image(IMG_BANNER_2);
	the_game.number[3] = load_image(IMG_BANNER_3);
	the_game.number[4] = load_image(IMG_BANNER_4);
	the_game.number[5] = load_image(IMG_BANNER_5);
	the_game.number[6] = load_image(IMG_BANNER_6);
	the_game.number[7] = load_image(IMG_BANNER_7);
	the_game.number[8] = load_image(IMG_BANNER_8);
	the_game.number[9] = load_image(IMG_BANNER_9);
	the_game.banner_life = load_image(IMG_BANNER_LIFE);
	the_game.banner_bomb = load_image(IMG_BANNER_BOMB);
	the_game.banner_range = load_image(IMG_BANNER_RANGE);
	the_game.banner_line = load_image(IMG_BANNER_LINE);
	the_game.banner_key = load_image(IMG_MAP_KEY);
	//the_game.bomb = NULL;

	return &the_game;
}

void game_free(t_game game) {
	assert(game);

	player_free(game->player);
	level_free(game->curr_level);
}

t_player game_get_player(t_game game) {
	assert(game);
	return game->player;
}

void game_banner_display(t_game game, SDL_Surface* screen) {
	assert(game);
	assert(screen);

	t_map map = level_get_curr_map(game_get_curr_level(game));

	SDL_Rect place;

	int i;
	place.y = (map_get_height(map)) * SIZE_BLOC;
	for (i = 0; i < map_get_width(map); i++) {
		place.x = i * SIZE_BLOC;
		SDL_BlitSurface(game->banner_line, NULL, screen, &place);
	}

	place.y = (map_get_height(map) * SIZE_BLOC) + SIZE_LINE;

	int white_bloc = ((map_get_width(map) * SIZE_BLOC) - 6 * SIZE_BLOC) / 4;

	place.x = white_bloc;
	SDL_BlitSurface(game->banner_life, NULL, screen, &place);
	place.x = white_bloc + SIZE_BLOC;
	// TODO : link lifes in banner and lifes of player  Done!
	if (player_get_nb_lifes(game_get_player(game)) >= 0
			&& player_get_nb_lifes(game_get_player(game)) < 10)
		SDL_BlitSurface(game->number[player_get_nb_lifes(game_get_player(game))],
				NULL, screen, &place);

	place.x = 2 * white_bloc + 2 * SIZE_BLOC;
	SDL_BlitSurface(game->banner_bomb, NULL, screen, &place);
	place.x = 2 * white_bloc + 3 * SIZE_BLOC;
	;
	if (player_get_nb_bomb(game_get_player(game)) >= 0	//manage bomb nb and banner
			&& player_get_nb_bomb(game_get_player(game)) < 10)
		SDL_BlitSurface(game->number[player_get_nb_bomb(game_get_player(game))],
				NULL, screen, &place);

	place.x = 3 * white_bloc + 4 * SIZE_BLOC;
	SDL_BlitSurface(game->banner_range, NULL, screen, &place);
	place.x = 3 * white_bloc + 5 * SIZE_BLOC;
	// TODO : link bomb_range in banner and bomb_range of player

	SDL_BlitSurface(game->number[player_get_range_bomb(game_get_player(game))], NULL, screen, &place);

	if(player_get_has_key(game->player)){
		place.x = 3 * white_bloc + 6 * SIZE_BLOC;
		SDL_BlitSurface(game->banner_key, NULL, screen, &place);
	}
}

void game_display(t_game game, SDL_Surface* screen) {
	assert(game);
	SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
	t_map map = level_get_curr_map(game_get_curr_level(game));
	game_banner_display(game, screen);
	level_display(game_get_curr_level(game), screen);
	player_display(game->player, screen);
	if(the_game.monster_list){
		monster_list_display(game->monster_list, screen, map, game->player);
	}

	if(game->bomb_list)
	{
		bomb_list_display(game->bomb_list, screen, map, game->player, game->monster_list,monster_list_get_type_cell(monster_list_get_head(game->monster_list)));
	}

	SDL_Flip(screen); // SDL_Flip -- swaps screen buffers -- update

}

t_level game_get_curr_level(t_game game) {
	return game->curr_level;
}
void game_pause(){
	int continuer=1;
	SDL_Event event;

	Uint32 time = SDL_GetTicks();

	while(continuer){
		while (SDL_PollEvent(&event)) {
			switch (event.type) {


			case SDL_KEYDOWN:
				switch(event.key.keysym.sym){

				case SDLK_p:
					continuer=0;
					Uint32 time_spent=SDL_GetTicks()-time;
					bomb_list_adapte_time(the_game.bomb_list, time_spent);
					break;
				}
				break;
			}
		}
	}
}

uint input_update(t_game game) {
	SDL_Event event;
	t_player player = game_get_player(game);
	t_map map = level_get_curr_map(game_get_curr_level(game));

	while (SDL_PollEvent(&event)) {
		switch (event.type) {
		case SDL_QUIT:
			return 1;
		case SDL_KEYDOWN:
			switch (event.key.keysym.sym) {
			case SDLK_ESCAPE:
				return 1;
			case SDLK_UP:
				player_set_current_way(player, NORTH);
				player_move(player, map);
				game_change_map(game);
				break;
			case SDLK_DOWN:
				player_set_current_way(player, SOUTH);
				player_move(player, map);
				game_change_map(game);
				break;
			case SDLK_RIGHT:
				player_set_current_way(player, EAST);
				player_move(player, map);
				game_change_map(game);
				break;
			case SDLK_LEFT:
				player_set_current_way(player, WEST);
				player_move(player, map);
				game_change_map(game);
				break;

			case SDLK_SPACE:
				// TODO Set a bomb
				if(player_get_nb_bomb(player) > 0){
					bomb_list_add(game->bomb_list, bomb_new(player_get_x(player), player_get_y(player), BOMB_RANGE_DEFAULT));
					player_dec_nb_bomb(player);
				}
				break;

			case SDLK_p:  //pause
				game_pause();
				break;

			case SDLK_b:  // cheat because it's easier to test the game
				player_inc_nb_bomb(player);
				break;

			case SDLK_c:
				player_inc_nb_lifes(player);
				break;

			case SDLK_r:
				player_inc_range_bomb(player);
				break;

			default:
				break;
			}

			break;
		}
	}
	return 0;
}

int game_update(t_game game) {
	if(input_update(game) == 1 || player_get_nb_lifes(game->player) == 0) {
		return 1; // exit game
	}
	// TODO monsters management ... cf monster_list_display

	return 0;
}


int game_change_map(t_game game){
	assert(game);

	int x=0;

	if(player_get_x(game->player)==0 && player_get_y(game->player)==11){
		if(level_get_cur_map(game->curr_level) < level_get_nb_maps(game->curr_level)-1){
			level_inc_cur_map(game->curr_level);
			x=1;
		}
	}
		/*
		else if(player_get_has_goal(game->player)==1 && level_get_nb_level(game->curr_level) <= NB_LEVEL_MAX){
			game->nb_level = level_inc_nb_level(game->curr_level);
			x=2;
		}*/


	if(player_get_x(game->player)==11 && player_get_y(game->player)==11){
		if(level_get_cur_map(game->curr_level)){
			level_dec_cur_map(game->curr_level);
			x=1;
		}
		/*else if(level_get_nb_level(game->curr_level)){
		game->curr_level=level_dec_nb_level(game->curr_level);
		x=2;
		}*/
	}

	if(x==1){
		player_from_map(game->player, level_get_curr_map(game_get_curr_level(game)));//place the player at the beginning of the map like first stage
		game->monster_list=NULL;
		game->monster_list=monster_list_from_map(level_get_curr_map(game_get_curr_level(game)), the_game.monster_list);
		game->bomb_list=NULL;
		the_game.bomb_list = bomb_list_init( bomb_new ( player_get_x(the_game.player), player_get_y(the_game.player), BOMB_RANGE_DEFAULT));
	}
	else if(x==2){
		player_from_map(game->player, level_get_curr_map(game_get_curr_level(game)));//place the player at the beginning of the map like first stage
		game->monster_list=NULL;
		game->monster_list=monster_list_from_map(level_get_curr_map(game_get_curr_level(game)), the_game.monster_list);
		game->bomb_list=NULL;
		the_game.bomb_list = bomb_list_init( bomb_new ( player_get_x(the_game.player), player_get_y(the_game.player), BOMB_RANGE_DEFAULT));

	}
	return 1;
}


